package cn.lingyangwl.agile.system.controller;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.lingyangwl.agile.common.security.annotation.InnerAuth;
import cn.lingyangwl.agile.file.excel.CusExcelExportUtil;
import cn.lingyangwl.agile.model.constants.SecurityCons;
import cn.lingyangwl.agile.model.constants.ValidationCons;
import cn.lingyangwl.agile.model.enums.BoolEnum;
import cn.lingyangwl.agile.model.module.auth.LoginUser;
import cn.lingyangwl.agile.ram.ActionType;
import cn.lingyangwl.agile.ram.RamResource;
import cn.lingyangwl.agile.system.assembly.SysUserAssembly;
import cn.lingyangwl.agile.system.model.entity.SysUser;
import cn.lingyangwl.agile.system.model.rqrs.log.LoginUserGetReq;
import cn.lingyangwl.agile.system.model.rqrs.user.*;
import cn.lingyangwl.agile.system.service.SysDeptService;
import cn.lingyangwl.agile.system.service.SysRoleService;
import cn.lingyangwl.agile.system.service.SysUserService;
import cn.lingyangwl.framework.core.response.Resp;
import cn.lingyangwl.framework.tool.core.StringUtils;
import cn.lingyangwl.framework.validation.group.InsertGroup;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import javax.validation.groups.Default;
import java.io.IOException;
import java.util.List;

/**
 * 用户管理
 * @author shenguangyang
 */
@Api(tags = "用户管理")
@RestController
@Validated
@RequestMapping("/user")
public class SysUserController {
    @Resource
    private SysUserService userService;
    @Resource
    private SysRoleService roleService;
    @Resource
    private SysDeptService deptService;

    @Resource
    private SysUserAssembly userAssembly;

    /**
     * 获取用户列表
     */
    @GetMapping("/pageUser")
    @RamResource(action = "sys:user:query", name = "查询用户", type = ActionType.READ)
    public Resp<IPage<UserResp>> pageUser(UserPageReq req) {
        IPage<UserResp> page = userService.pageUser(req);
        return Resp.ok(page);
    }

    @PostMapping("/export")
    @RamResource(action = "sys:user:export", name = "导出用户", type = ActionType.READ)
    public void export(HttpServletResponse response, UserPageReq req) throws Exception {
        List<UserResp> list = userService.list(req);
        ExportParams params = new ExportParams();
        params.setType(ExcelType.HSSF);
        CusExcelExportUtil.exportExcel(response, params, "用户数据.xls", UserResp.class, list);
    }

    @PostMapping("/listUser")
    @RamResource(action = "sys:user:listUser", name = "查询用户", type = ActionType.READ)
    public Resp<List<UserResp>> listUser(UserPageReq query) throws IOException {
        List<UserResp> list = userService.list(query);
        return Resp.ok(list);
    }

    /**
     * 获取当前用户信息
     */
    @InnerAuth
    @PostMapping("/getLoginUser")
    public Resp<LoginUser> getLoginUser(@RequestBody @Validated LoginUserGetReq req) {
        return Resp.ok(userService.getLoginUser(req));
    }

    /**
     * 冻结用户
     */
    @PutMapping("/frozenBatch")
    @RamResource(action = "sys:user:frozenBatch", name = "冻结用户", type = ActionType.WRITE)
    public Resp<?> frozenBatch(@RequestBody @Validated UserStatusUpdateReq req) {
        userService.updateBatchUserStatus(req);
        return Resp.ok();
    }

    /**
     * 状态修改
     *
     */
    @PutMapping("/changeStatus")
    @RamResource(action = "sys:user:changeStatus", name = "更改用户状态", type = ActionType.WRITE)
    public Resp<?> changeStatus(@RequestBody SysUser user) {
        return userService.updateUserStatus(user) ? Resp.ok() : Resp.fail("更新失败");
    }

    /**
     * 根据用户编号获取详细信息
     */
    @RamResource(action = "sys:user:query", name = "查询用户详情", type = ActionType.READ)
    @GetMapping(value = { "/getUserDetails"})
    public Resp<UserDetailsResp> getUserDetails(@RequestParam(value = "userId", required = false) @NotNull(message = ValidationCons.NOT_EMPTY)
                                                    Long userId) {
        UserResp user = userService.getUserById(userId);
        UserDetailsResp resp = userAssembly.toUserDetailsResp(user);
        resp.setDeptList(deptService.listUserDept(new UserDeptListReq(userId)));
        return Resp.ok(resp);
    }

    @GetMapping("/getById")
    @RamResource(action = "sys:user:query", name = "查询用户", type = ActionType.READ)
    public Resp<UserResp> getById(@RequestParam(value = "id") Long userId) {
        return Resp.ok(userService.getUserById(userId));
    }

    /**
     * 新增用户
     */
    @PostMapping("/save")
    @RamResource(action = "sys:user:save", name = "保存用户", type = ActionType.WRITE)
    public Resp<Long> save(@Validated({InsertGroup.class, Default.class}) @RequestBody UserSaveReq req) {
        // user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        return Resp.ok(userService.saveUser(req));
    }

    /**
     * 修改用户
     */
    @PostMapping("/update")
    @RamResource(action = "sys:user:update", name = "更新用户", type = ActionType.WRITE)
    public Resp<?> update(@Validated @RequestBody UserUpdateReq req) {
        SysUser user = userAssembly.toUser(req);
        userService.checkUserAllowed(user.getUserId());
        // user.setUpdateBy(SecurityUtils.getUserName());
        return userService.updateById(user) ? Resp.ok() : Resp.fail("更新失败");
    }

    /**
     * 删除用户
     */
    @DeleteMapping("/delete")
    @RamResource(action = "sys:user:delete", name = "删除用户", type = ActionType.WRITE)
    public Resp<?> delete(@RequestParam(value = "id") String userId) {
        return userService.deleteLogicUserById(Long.parseLong(userId)) ? Resp.ok() : Resp.fail("删除失败");
    }


    @RamResource(action = "sys:user:query", name = "查询用户", type = ActionType.READ)
    @GetMapping(value = "/user/listUserByIds", headers = SecurityCons.HEADER_FROM_IN)
    public Resp<List<UserResp>> listUserByIds(@RequestParam(value = "userIds") List<Long> userIds) {
        return Resp.ok(userService.listUserByIds(userIds));
    }

    /**
     * 回收站
     */
    @RamResource(action = "sys:user:recycleBin", name = "查询回收站中的用户", type = ActionType.READ)
    @GetMapping(value = "/recycleBin")
    public Resp<IPage<UserResp>> recycleBin() {
        UserPageReq query = new UserPageReq();
        query.setDelFlag(BoolEnum.TRUE.getCode());
        IPage<UserResp> list = userService.pageUser(query);
        return Resp.ok(list);
    }

    /**
     * 删除回收站的数据
     */
    @DeleteMapping(value = "/deleteRecycleBin")
    @RamResource(action = "sys:user:deleteRecycleBin", name = "删除回收站用户", type = ActionType.WRITE)
    public Resp<?> deleteRecycleBin(@RequestBody @Validated UserRecycleBinReq req) {
        userService.deleteUserByIds(StringUtils.toList(req.getUserIds(), ",", Long.class));
        return Resp.ok();
    }

    /**
     * 从回收站中恢复用户
     */
    @PutMapping(value = "/recoverRecycleBin")
    @RamResource(action = "sys:user:recoverRecycleBin", name = "从回收站中恢复用户", type = ActionType.WRITE)
    public Resp<?> recoverRecycleBin(@RequestBody @Validated UserRecycleBinReq req) {
        userService.recoverRecycleBin(req);
        return Resp.ok();
    }

    /**
     * 注册用户
     */
    @PostMapping("/register")
    public Resp<?> register(@RequestBody UserRegisterReq rq) {
        userService.register(rq);
        return Resp.ok();
    }

    @PostMapping(value = "/deleteLoginUser")
    @RamResource(action = "sys:user:deleteLoginUser", name = "删除登录的用户", type = ActionType.WRITE)
    public Resp<?> deleteLoginUser(@RequestBody @Validated LoginUserDeleteReq req) {
        userService.deleteLogicUser(req);
        return Resp.ok();
    }

    /**
     * 内网访问
     */
    @GetMapping("/getUserByAccount")
    public Resp<SysUser> getUserByAccount(@RequestParam("account") String account) {
        return Resp.ok(userService.getUserByAccount(account));
    }
}